import * as AgentApi from '@/api/call/agent'
import { usePhoneStore } from '@/store/modules/phone'
import { ElMessage, ElMessageBox } from 'element-plus'
import { updateAgentStatus } from '@/api/call/agent'
import Log from '@/utils/log'
import { AudioPlayer } from './AudioPlayer'

// 更新手机状态
const updatePhoneStatus = async () => {
  const data = await updateAgentStatus({ action: 'idle' })
  console.log(data, '---')
}

export function useWebPhone() {
  const useStore = usePhoneStore()

  // 会话状态
  const SESSION_STATUS = {
    RINGING: 'ringing',
    PROGRESS: 'progress',
    ACCEPTED: 'accepted',
    REJECT: 'reject',
    CANCEL: 'cancel',
    FAILED: 'failed',
    ENDED: 'ended',
    MISSED: 'missed'
  }

  const TYPE_IN = 'incoming'
  const TYPE_OUT = 'outgoing'
  const TYPE = {
    incoming: 'incoming',
    outgoing: 'outgoing'
  }

  // 话机对象
  let PHONE = null

  // 外呼参数
  let PARAMS = null

  let IS_HANGUP = false

  const stun = 'stun:211.159.161.254'

  // 监听话机注册状态
  const onRegListener = (type, data) => {
    if (type == 'reg.registered') {
      // console.info('RegRegistered: >>> ', data)
      ElMessage.success('SIP话机模式已激活')
      useStore.setSipRegSuccess(true)
    } else if (type == 'reg.unregistered') {
      useStore.clearAll()
      useStore.setSipRegSuccess(false)
      // 下线
      // console.warn('RegUnregistered: >>> ', data)
    } else if (type == 'reg.failed') {
      useStore.clearAll()
      useStore.setSipRegSuccess(false)
      // 注册失败
      // console.error('RegFailed: >>> ', data)
    }
  }

  // let session = {
  //   type: undefined, // 类型： incoming , outgoing
  //   callee: undefined, // 被叫
  //   reqNo: undefined, // 请求id
  //   status: undefined, // 状态
  //   time: 0 // 通话时长
  // }

  const sessionListener = async (type, data, options) => {
    console.info('==============================================')
    console.info('sessionListener ---------- type === \r\n', type)
    console.info('sessionListener ---------- data === \r\n', data)
    console.info('sessionListener ---------- options === \r\n', options)
    console.info('==============================================')

    let session = null

    if (type == 'outgoing.connecting') {
      session = {
        type: TYPE_OUT, // 类型： incoming , outgoing
        callee: data.callee || '', // 被叫
        reqNo: data.userdata || '', // 请求id
        status: SESSION_STATUS.RINGING, // 状态
        time: 0, // 通话时长
        source: PARAMS && PARAMS.source,
        sourceId: PARAMS && PARAMS.sourceId
      }
    } else if (type == 'outgoing.progress') {
      session = useStore.getSession
      if (session) {
        session.status = SESSION_STATUS.PROGRESS
      }
    } else if (type == 'outgoing.failed') {
      session = useStore.getSession
      if (session) {
        // 如果上个状态是progress, 那么这里需要给到客户拒接, 或者坐席挂断
        if (session.status == SESSION_STATUS.PROGRESS) {
          if (IS_HANGUP) session.status = SESSION_STATUS.CANCEL
          else session.status = SESSION_STATUS.REJECT
        } else {
          session.status = SESSION_STATUS.FAILED
        }
      }
      PARAMS = null
      updatePhoneStatus()
      useStore.setNeedCall(true)
    } else if (type == 'outgoing.ended') {
      session = useStore.getSession
      if (session) {
        if (IS_HANGUP) session.status = SESSION_STATUS.CANCEL
        else session.status = SESSION_STATUS.ENDED
      }
      PARAMS = null
      updatePhoneStatus()
      useStore.setNeedCall(true)
    } else if (type == 'outgoing.accecpted') {
      session = useStore.getSession
      if (session) {
        session.status = SESSION_STATUS.ACCEPTED
      }
      // seatingAnswers(session)
    }
    if (!session) {
      session = {
        type: TYPE_OUT, // 类型： incoming , outgoing
        callee: '', // 被叫
        reqNo: '', // 请求id
        status: SESSION_STATUS.ENDED, // 状态
        time: 0, // 通话时长
        source: 'none',
        sourceId: null
      }
    }

    // incoming handle ==== 先写到一个函数里面吧
    if (type == 'incoming.notify') {
      // 来电通知
      // 1. 这里需要从data.name 中获取被叫手机号赋值给callee
      // 2. reqNo 在本地生成，默认规则是坐席工号+callee
      // 3. status 是振铃中
      // 4. source和sourceId为空；
      // 5. 在坐席工作台中，获取session.type=incoming 的属于群呼任务呼入来的话单。
      const callee = data.name
      const agentNumber = useStore.agentNumber
      const param = {
        callId: `${agentNumber}${callee}`,
        callee,
        agentNumber
      }
      const reqNo = await AgentApi.mapCallId(param)
      session = {
        type: TYPE_IN, // 类型： incoming , outgoing
        callee: param.callee || '', // 被叫
        reqNo, // 请求id
        status: SESSION_STATUS.RINGING, // 状态
        time: 0, // 通话时长
        source: 'none',
        sourceId: null
      }
      // 自动接听的开关 ->
      if (useStore.autoAnswer) {
        PHONE.answer()
      }
      useStore.setNotificationNum()
      // 坐席中心最小化时显示
      if (useStore.getCallWorkSize == 'mini') useStore.setCallWorkSize('primary')
    } else if (type == 'incoming.accecpted') {
      // 坐席侧接起
      session = useStore.session
      if (session) {
        session.status = SESSION_STATUS.ACCEPTED
      }
    } else if (type == 'incoming.ended') {
      // 正常挂断
      session = useStore.session
      if (session) {
        if (IS_HANGUP) session.status = SESSION_STATUS.CANCEL
        else session.status = SESSION_STATUS.ENDED
      }
    } else if (type == 'incoming.failed') {
      // 连接失败
      session = useStore.session
      if (session) {
        if (session.status == SESSION_STATUS.PROGRESS) session.status = SESSION_STATUS.REJECT
        else session.status = SESSION_STATUS.FAILED
      }
    }
    if (!session) {
      session = {
        type: TYPE_IN, // 类型： incoming , outgoing
        callee: '', // 被叫
        reqNo: '', // 请求id
        status: SESSION_STATUS.ENDED, // 状态
        time: 0, // 通话时长
        source: 'none',
        sourceId: null
      }
    }

    IS_HANGUP = false
    useStore.setSession(session)
  }

  /*坐席接听时，调用接口*/
  const seatingAnswers = async (session) => {
    const obj = JSON.parse(JSON.stringify(session))
    const res = await AgentApi.agentInfo()
    const data = {
      callId: `${res.agentNumber}${session.callee}`,
      callee: session.callee,
      agentNumber: res.agentNumber
    }
    const result = await AgentApi.mapCallId(data)
    if (result) {
      obj.reqNo = result
      useStore.setSession(obj)
    }
  }

  const reg = async () => {
    const accountInfo = await AgentApi.getAccountInfo({ channelId: useStore.getChannelId })
    //
    if (accountInfo.user) {
      useStore.setAgentNumber(accountInfo.user)
    }
    PHONE = new WebPhoneSDK({
      lib: JsSIP,
      debug: false,
      debugLib: false,
      user: accountInfo.user,
      ha1: accountInfo.ha1,
      realm: accountInfo.realm,
      server: 'haiwei.org.cn',
      audioElement: document.getElementById('remoteAudio'),
      httpsConfirmFrame: 'httpsConfirmFrame',
      pcConfig: { iceServers: [{ urls: [stun] }] },
      events: {
        'reg.registered': (type, data) => onRegListener(type, data),
        'reg.unregistered': (type, data) => onRegListener(type, data),
        'reg.failed': (type, data) => onRegListener(type, data),
        'incoming.notify': (type, data, options) => sessionListener(type, data, options),
        'incoming.failed': (type, data, options) => sessionListener(type, data, options),
        'incoming.ended': (type, data, options) => sessionListener(type, data, options),
        'incoming.accecpted': (type, data, options) => sessionListener(type, data, options),
        'outgoing.connecting': (type, data, options) => sessionListener(type, data, options),
        'outgoing.progress': (type, data, options) => sessionListener(type, data, options),
        'outgoing.failed': (type, data, options) => sessionListener(type, data, options),
        'outgoing.ended': (type, data, options) => sessionListener(type, data, options),
        'outgoing.accecpted': (type, data, options) => sessionListener(type, data, options)
      }
    })
    PHONE.start({})

    // 默认登录坐席
    await setLogin()

    // 默认置忙坐席
    await setBusy()
  }

  const call = async (params) => {
    console.log(params, 'params')
    const data = await AgentApi.simpleCall(params)
    localStorage.setItem('CALL_TASK_REQ_NO', data.reqNo)
    PHONE.call(params.callee, { userdata: data.reqNo, cid: data.caller, callee: params.callee })
    PARAMS = params
  }

  const answer = () => {
    PHONE.answer()
  }

  const hangup = () => {
    try {
      IS_HANGUP = true
      PHONE.ua.terminateSessions()
    } catch (e) {
      PHONE.reject()
      console.error('挂断方式1： 失败', e)
    }
  }
  // 话机状态操作： 登录、退出、置闲、置忙
  // 配合话机状态缓存key： store/agentStatus=login/logout/busy/idle

  const setLogin = async () => {
    await AgentApi.handleAgent({
      type: 'agentLogin',
      channelId: useStore.getChannelId
    })
    useStore.setAgentStatus('login')
  }

  const setLogout = async () => {
    await AgentApi.handleAgent({
      type: 'agentLogout',
      channelId: useStore.getChannelId
    })
    useStore.setAgentStatus('logout')
    PHONE.stop()
  }

  const setBusy = async () => {
    await AgentApi.handleAgent({
      type: 'agentSetBusy',
      channelId: useStore.getChannelId
    })
    useStore.setAgentStatus('busy')
  }

  const setIdle = async () => {
    await AgentApi.handleAgent({
      type: 'agentSetIdle',
      channelId: useStore.getChannelId
    })
    useStore.setAgentStatus('idle')
  }

  return {
    reg,
    call,
    answer,
    hangup,
    setLogin,
    setLogout,
    setBusy,
    setIdle
  }
}
